package com.tbit.uqbike.robot.net.aio.client;

import com.tbit.uqbike.robot.VirTer;
import com.tbit.uqbike.robot.net.Wa206Handler;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;

public class AsyncClientHandler implements CompletionHandler<Void, AsyncClientHandler> {
    private AsynchronousSocketChannel clientChannel;
    private String host;
    private int port;
    private TcpClientStatus status;
    private ReadHandler readHandler;
    private WriteHandler writeHandler;
    private String clientId;
    private boolean bReConn;
    private int iRecvBufferSize;
    public VirTer ter;

    public AsyncClientHandler(String host, int port) {
        this.host = host;
        this.port = port;
        this.status = TcpClientStatus.Normal;
        this.clientId = UUID.randomUUID().toString();
        this.iRecvBufferSize = 256;

        this.readHandler = new Wa206Handler(this);
        this.writeHandler = new WriteHandler(this);
    }

    public int getiRecvBufferSize() {
        return iRecvBufferSize;
    }

    public void setiRecvBufferSize(int iRecvBufferSize) {
        this.iRecvBufferSize = iRecvBufferSize;
    }

    public boolean isbReConn() {
        return bReConn;
    }

    public void setbReConn(boolean bReConn) {
        this.bReConn = bReConn;
    }

    public AsynchronousSocketChannel getClientChannel() {
        return clientChannel;
    }

    public String getClientId() {
        return clientId;
    }

    public TcpClientStatus getStatus() {
        return status;
    }

    public void beginConnect() {
        //发起异步连接操作，回调参数就是这个类本身，如果连接成功会回调completed方法
        //创建异步的客户端通道
        if (Objects.equals(TcpClientStatus.Normal, this.status)) {
            try {
                clientChannel = AsynchronousSocketChannel.open();
            } catch (IOException e) {
                e.printStackTrace();
                return;
            }
            clientChannel.connect(new InetSocketAddress(host, port), this, this);
            this.status = TcpClientStatus.Connecting;
        }
    }

    public void closeConnect() {
        this.status = TcpClientStatus.Normal;
        try {
            if (clientChannel.isOpen()) {
                System.err.println("通道关闭...");
                clientChannel.close();
            }
        } catch (IOException e) {
        }
    }


    //连接服务器成功
    //意味着TCP三次握手完成
    @Override
    public void completed(Void result, AsyncClientHandler attachment) {
        this.status = TcpClientStatus.Connected;
        // 连接成功后开始接收数据
        readHandler.beginRead();
        //System.out.println("客户端成功连接到服务器,开始接收数据...");
    }

    //连接服务器失败
    @Override
    public void failed(Throwable exc, AsyncClientHandler attachment) {
        closeConnect();
    }

    //向服务器发送消息
    public void sendMsg(String msg) {
        byte[] req = msg.getBytes();
        sendBytes(req);
    }

    public void sendBytes(byte[] bs) {
        if (Objects.equals(this.status, TcpClientStatus.Connected)) {
            ByteBuffer writeBuffer = ByteBuffer.allocate(bs.length);
            writeBuffer.put(bs);
            writeBuffer.flip();
            //异步写
            clientChannel.write(writeBuffer, writeBuffer, writeHandler);
        }
    }
}
